﻿
// DataShowDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "DataShow.h"
#include "DataShowDlg.h"
#include "afxdialogex.h"
#include<gl/glut.h>
#include "DataProcess.h"
#include "Sample.h"
#include "Energy.h"
#include "Mtime.h"
#include "ini.h"
#include "SingleDouble.h"
#include "ERcalculate.h"
#include "engine.h"
#include "mclmcrrt.h"
#include "mclcppclass.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CDataShowDlg 对话框



CDataShowDlg::CDataShowDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CDataShowDlg::IDD, pParent)
	,samplenum(0)
	,energynum(0)
	,m_sampledatapos(0)
	,m_energydatapos(0)
	,m_channel(0)
	,m_boardnum(0)
{
	m_sample=NULL;
	x=NULL;
	y=NULL;
	m_energy=NULL;
	Fir_sample_time=NULL;
	Serial_NUM=NULL;
	memset(check, 0, sizeof(BYTE) * 72 * 6);
	memset(check2, 0, sizeof(BYTE) * 72 * 6);
	memset(frequent,0,sizeof(long)*160);
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDataShowDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_FIGURE, m_picturectrl);
}

BEGIN_MESSAGE_MAP(CDataShowDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_DESTROY()
	ON_WM_TIMER()
ON_BN_CLICKED(IDC_RUNSAMPLES, &CDataShowDlg::OnBnClickedRunsamples)
ON_BN_CLICKED(IDC_SAVEFIGURE, &CDataShowDlg::OnBnClickedSavefigure)
ON_BN_CLICKED(IDC_SAMPLESETTING, &CDataShowDlg::OnBnClickedSamplesetting)
ON_BN_CLICKED(IDC_FILEPATH, &CDataShowDlg::OnBnClickedFilepath)
ON_BN_CLICKED(IDC_SAMPLENEXT, &CDataShowDlg::OnBnClickedSamplenext)
ON_BN_CLICKED(IDC_ENERGYSETTING, &CDataShowDlg::OnBnClickedEnergysetting)
ON_BN_CLICKED(IDC_ENERGYRUN, &CDataShowDlg::OnBnClickedEnergyrun)
ON_BN_CLICKED(IDC_ENERGYNEXT, &CDataShowDlg::OnBnClickedEnergynext)
ON_BN_CLICKED(IDC_TIMESETTING, &CDataShowDlg::OnBnClickedTimesetting)
END_MESSAGE_MAP()


// CDataShowDlg 消息处理程序

BOOL CDataShowDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO:  在此添加额外的初始化代码

	m_threshold[0]=Cini::ReadInt(_T("Sample"), _T("Threshold1"), _T("DataShow.ini"));
	m_threshold[1]=Cini::ReadInt(_T("Sample"), _T("Threshold2"), _T("DataShow.ini"));
	m_threshold[2]=Cini::ReadInt(_T("Sample"), _T("Threshold3"), _T("DataShow.ini"));
	m_threshold[3]=Cini::ReadInt(_T("Sample"), _T("Threshold4"), _T("DataShow.ini"));
	m_radio=Cini::ReadInt(_T("Sample"), _T("Radio"), _T("DataShow.ini"));
	m_channel=Cini::ReadInt(_T("Sample"), _T("channelvalue"), _T("DataShow.ini"));
	m_boardnum=Cini::ReadInt(_T("Sample"), _T("boardnum"), _T("DataShow.ini"));
	m_radio_energy=Cini::ReadInt(_T("Energy"), _T("Radio"), _T("DataShow.ini"));
	m_board_energy=Cini::ReadInt(_T("Energy"), _T("boardnum"), _T("DataShow.ini"));
	m_board_energy2=Cini::ReadInt(_T("Energy"), _T("boardnum2"), _T("DataShow.ini"));
	m_chann_energy=Cini::ReadInt(_T("Energy"), _T("channelvalue"), _T("DataShow.ini"));
	//初始化openGL
	InitializeOpenGL();
	CSize size= getClientbmpsize();
	unsigned int NbBytes = 3 * size.cx * size.cy;
	pPixelData = new unsigned char[NbBytes];
	
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CDataShowDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CDataShowDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDataShowDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



BOOL CDataShowDlg::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO:  在此添加专用代码和/或调用基类
	//  the CREATESTRUCT cs
	cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
	return CDialogEx::PreCreateWindow(cs);
}

BOOL CDataShowDlg::SetupPixelFormat()
{
	static PIXELFORMATDESCRIPTOR pfd = 
    {
        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
        1,                              // version number
        PFD_DRAW_TO_WINDOW |            // support window
        PFD_SUPPORT_OPENGL |            // support OpenGL
        PFD_DOUBLEBUFFER,                // double buffered
        PFD_TYPE_RGBA,                  // RGBA type
        24,                             // 24-bit color depth
        0, 0, 0, 0, 0, 0,               // color bits ignored
        0,                              // no alpha buffer
        0,                              // shift bit ignored
        0,                              // no accumulation buffer
        0, 0, 0, 0,                     // accum bits ignored
        16,                             // 16-bit z-buffer
        0,                              // no stencil buffer
        0,                              // no auxiliary buffer
        PFD_MAIN_PLANE,                 // main layer
        0,                              // reserved
        0, 0, 0                         // layer masks ignored
    };
    int m_nPixelFormat = ::ChoosePixelFormat(hrenderDC, &pfd);
    if ( m_nPixelFormat == 0 )
    {
       return FALSE;
    }
    if ( ::SetPixelFormat(hrenderDC, m_nPixelFormat, &pfd) == FALSE)
    {
       return FALSE;
    }
    return TRUE;
}


void CDataShowDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO:  在此处添加消息处理程序代码
	if (x!=NULL)
	{
		delete []x;
		x=NULL;
	}
	if (y!=NULL)
	{
		delete []y;
		y=NULL;
	}
	if (m_sample!=NULL)
	{
		delete []m_sample;
		m_sample=NULL;
	}
	if (m_energy!=NULL)
	{
		delete []m_energy;
		m_energy=NULL;
	}
	if (Fir_sample_time!=NULL)
	{
		delete []Fir_sample_time;
		Fir_sample_time=NULL;
	}
	if (Serial_NUM!=NULL)
	{
		delete [] Serial_NUM;
		Serial_NUM=NULL;
	}
	SingleDoubleTerminate();
	ERcalculateTerminate();
	mclTerminateApplication;
	//Make the RC non-current
	if (::wglMakeCurrent(NULL, NULL) == FALSE)
	{
		MessageBox(_T("Could not make RC non-current"));
	}

	//Delete the rendering context
	if (::wglDeleteContext(m_hRC) == FALSE)
	{
		MessageBox(_T("Could not delete RC"));
	}

}


BOOL CDataShowDlg::InitializeOpenGL()
{
	CWnd *wnd = GetDlgItem(IDC_FIGURE);
	hrenderDC = ::GetDC(wnd->m_hWnd);
	if (hrenderDC == NULL)
	{
		MessageBox(_T("Error Obtaining DC"));
		return FALSE;
	}
	//Failure to set the pixel format
	if (!SetupPixelFormat())
	{
		return FALSE;
	}
	//Create Rendering Context
	m_hRC = ::wglCreateContext(hrenderDC);
	//Failure to Create Rendering Context
	if (m_hRC == 0)
	{
		MessageBox(_T("Error Creating RC"));
		return FALSE;
	}
	//Make the RC Current
	if (::wglMakeCurrent(hrenderDC, m_hRC) == FALSE)
	{
		MessageBox(_T("Error making RC Current"));
		return FALSE;
	}
	//Specify Black as the clear color
	::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
	//Specify the back of the buffer as clear depth
	::glClearDepth(1.0f);
	//Enable Depth Testing
	::glEnable(GL_DEPTH_TEST);
	return TRUE;
}

void CDataShowDlg::RenderScene()
{
	// Clear out the color & depth buffers
	::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


	const GLfloat factor = 0.01f;
	GLfloat x;
	glPushMatrix();
	glTranslatef(-0.9,-0.9,0.0);
	glColor3f(0.0f, 0.0f, 0.0f);
	glBegin(GL_LINES);
	glVertex2f(-1.0f, 0.0f);
	glVertex2f(2.0f, 0.0f);         // 以上两个点可以画x轴
	glVertex2f(0.0f, -1.0f);
	glVertex2f(0.0f, 2.0f);         // 以上两个点可以画y轴
	glEnd();
	
	
	glColor3f(1.0f, 0.0f, 0.0f);
	glBegin(GL_LINE_STRIP);
	int i=0;
	for (x = 0.0f / factor; x < 2.0f / factor; x += 0.01f)
	{
		i=x/factor;
		glVertex2f(/*sampleplotdata[i]*/x*factor,/*sampleplotdata[7501+i]/200*/0.5f);			
	}	
	glEnd();
	// Tell OpenGL to flush its pipeline
	::glFinish();

	CSize size = getClientbmpsize();
	::glReadPixels(0, 0, size.cx, size.cy, GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);
	glPopMatrix();
	// Now Swap the buffers
	::SwapBuffers(hrenderDC);	

}


void CDataShowDlg::DrawSamplefigure()
{
	CWnd *wnd = GetDlgItem(IDC_FIGURE);	
	CDC *pDC=wnd->GetDC();
	CRect rect;
	wnd->GetClientRect(&rect);     //取画图客户区大小
	CSize size(rect.Width(), rect.Height());

	wnd->Invalidate();
	wnd->UpdateWindow();
	pDC->FillSolidRect(&rect,RGB(255, 255, 255));
	

	//确定坐标图预留的空白大小
	const int mybottom=50;
	const int myleft=82;
	//绘制X，Y轴
	pDC->MoveTo(myleft-22,size.cy-mybottom);
	pDC->LineTo(size.cx,size.cy-mybottom);
	//Y轴从图形区域最底端到最顶端
	pDC->MoveTo(myleft-22,size.cy-mybottom);
	pDC->LineTo(myleft-22,0);
	//确定每个显示刻度之间的宽度
	CString str;
	//X轴
	for(int i=0;i<=7;i++)
	{
		if (i==0)
		{
			str.Format(_T("%d"),-4);
			pDC->MoveTo(myleft,size.cy-mybottom);
			pDC->LineTo(myleft,size.cy-mybottom+5);
			pDC->TextOut(myleft-30,size.cy-(mybottom-5),str);	
		}
		str.Format(_T("%d"),i*20);		
		pDC->MoveTo(myleft+110*i,size.cy-mybottom);
		pDC->LineTo(myleft+110*i,size.cy-mybottom+5);
		pDC->TextOut(myleft+110*i,size.cy-(mybottom-5),str);	
	}

	double maxY=sampleplotdata[7501];
	for (int i=0;i<7501;i++)
	{
		maxY=maxY>sampleplotdata[i+7501]?maxY:sampleplotdata[i+7501];
	}
	double factor=(rect.Height()-mybottom-20)/maxY;
	//y轴
	for(int i=0;i<(size.cy-mybottom)/(100*factor);i++)
	{
		str.Format(_T("%d"),i*100);
		pDC->MoveTo(myleft-27,size.cy-(mybottom+100*factor*i));
		pDC->LineTo(myleft-22,size.cy-(mybottom+100*factor*i));
		pDC->TextOut(myleft-52,size.cy-(mybottom+100*factor*i+5),str);
	}
	//绘制X，Y轴的变量名
	pDC->TextOut(size.cx/2,size.cy-20,_T("时间(ns)"));
	pDC->TextOut(0,6,_T("电压(mv)"));

	
	//写图例
	CBrush Brush; 
	Brush.CreateSolidBrush(RGB(0,0,255)); 
	pDC->SelectObject(Brush);
	pDC->BeginPath(); 
	pDC->Ellipse(size.cx-256,34,size.cx-244,46); 
	pDC->EndPath(); 
	pDC->SelectObject(&Brush); 
	pDC->FillPath(); 
	pDC->TextOut(size.cx-230,30,_T("Sample Points"));
	pDC->TextOut(size.cx-230,5,_T("Fitting Curve"));

	//写板号和通道号
	str.Format(_T("%d"),m_sample[samplenum].boardnum+1);
	pDC->TextOut(size.cx-256,60,_T("板号:")+str);
	str.Format(_T("%d"),m_sample[samplenum].channel+1);
	pDC->TextOut(size.cx-256,80,_T("通道号:")+str);

	//标注拟合点
	for (int i=0;i<8;i++)
	{	
		if (i<4)
		{	
			pDC->BeginPath(); 
			pDC->Ellipse(myleft+m_sample[samplenum].Time[i]*5.5-6,rect.Height()-mybottom-m_threshold[i]*factor-6,
				myleft+m_sample[samplenum].Time[i]*5.5+6,rect.Height()-mybottom-m_threshold[i]*factor+6); 
			pDC->EndPath(); 
			pDC->SelectObject(&Brush); 
			pDC->FillPath(); 
		}
		else
		{	
			pDC->BeginPath(); 
			pDC->Ellipse(myleft+m_sample[samplenum].Time[i]*5.5-6,rect.Height()-mybottom-m_threshold[7-i]*factor-6,
				myleft+m_sample[samplenum].Time[i]*5.5+6,rect.Height()-mybottom-m_threshold[7-i]*factor+6); 
			pDC->EndPath(); 
			pDC->SelectObject(&Brush); 
			pDC->FillPath(); 
		}
	}


	CPen pen_line;
	pen_line.CreatePen(PS_SOLID,1,RGB(255,0,0));
	pDC->SelectObject(pen_line);
	pDC->MoveTo(size.cx-256,15);
	pDC->LineTo(size.cx-235,15);
	//绘制曲线。由于绘图坐标的Y轴是向下延升，所以这里每个点的Y值是用
	//图象高度减去y值大小

	for (int i=0;i<7501;i++)
	{
		if (i==7500)
		{
			pDC->MoveTo(myleft+sampleplotdata[i]*5.5,(rect.Height()-mybottom-sampleplotdata[i+7501]*factor));
			break;
		}
		pDC->MoveTo(myleft+sampleplotdata[i]*5.5,(rect.Height()-mybottom-sampleplotdata[i+7501]*factor));
		pDC->LineTo(myleft+sampleplotdata[i+1]*5.5,(rect.Height()-mybottom-sampleplotdata[i+7501+1]*factor));
	}
	
	
	//释放设备描述符
	ReleaseDC(pDC);
}

void CDataShowDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnTimer(nIDEvent);
}



long CDataShowDlg::sampledata_process()
{
	byte temp_channel[2],temp_time[8];
	double timemin;
	m_sample=new Sample[m_filelength / 67];
	for (int i = 0;i < m_filelength / 67;i++)
	{
		if (i== m_filelength / 67/2)
		{
			m_sampledatapos=20;
		}
		m_sample[i].boardnum = *(m_sample_data + i*67);
		for (int j = 0;j < 2;j++)
		{
			 temp_channel[j]=*(m_sample_data +j+1+ i*67);
			 m_sample[i].channel = *(USHORT*)&temp_channel;
		}
		check[m_sample[i].channel][m_sample[i].boardnum]=1;
		for (int k = 0;k < 8;k++)
		{
			for (int m = 0;m < 8;m++)
			{
				temp_time[m] = *(m_sample_data + m +k*8+ 3 + i * 67);				
			}	
			m_sample[i].Time[k] = *(double*)&temp_time;
		}
		for (int k = 0;k < 8;k++)
		{
				timemin = m_sample[i].Time[0];
				timemin = timemin < m_sample[i].Time[k] ? timemin: m_sample[i].Time[k];
		}		
		for (int m=0;m<8;m++)
		{
			m_sample[i].Time[m] = m_sample[i].Time[m] - timemin;
		}
		
	}
	
	delete[]m_sample_data;
	m_sample_data = NULL;
	m_sampledatapos=40;
	if (!SingleDoubleInitialize())
	{		
	}	
	m_sampledatapos=90;
    mwArray x(1, 8, mxDOUBLE_CLASS);
    mwArray th(1, 4, mxDOUBLE_CLASS);
	mwArray plotdata(1, 15002, mxDOUBLE_CLASS);
	x.SetData(m_sample[0].Time, 8);
	th.SetData(m_threshold, 4);		
	SingleDouble(1, plotdata, th, x);
	plotdata.GetData(sampleplotdata,15002);
	samplenum=0;
	m_sampledatapos=100;

			
	return m_filelength/67;
}

CSize CDataShowDlg::getClientbmpsize()
{
	CRect rect;
	m_picturectrl.GetClientRect(&rect);     //取画图客户区大小
	CSize size(rect.Width(), rect.Height());
	TRACE("client zone:(%d;%d)\n", size.cx, size.cy);
	size.cx -= size.cx % 4;
	TRACE("final client zone:(%d;%d)\n", size.cx, size.cy);
	return size;
}

DWORD WINAPI CDataShowDlg::SampleThread(LPVOID lpParam)
{
	CDataShowDlg* pDlg = (CDataShowDlg*)lpParam;
	pDlg->sampledata_process();
	return 0;
}

DWORD WINAPI CDataShowDlg::EnergyThread(LPVOID lpParam)
{
	CDataShowDlg* pDlg = (CDataShowDlg*)lpParam;
	pDlg->energydata_process();
	return 0;
}

void CDataShowDlg::DrawEnergyfigure()
{
	CWnd *wnd = GetDlgItem(IDC_FIGURE);	
	CDC *pDC=wnd->GetDC();
	CRect rect;
	wnd->GetClientRect(&rect);     //取画图客户区大小
	CSize size(rect.Width(), rect.Height());

	wnd->Invalidate();
	wnd->UpdateWindow();
	pDC->FillSolidRect(&rect,RGB(255, 255, 255));


	//确定坐标图预留的空白大小
	const int mybottom=50;
	const int myleft=80;
	//绘制X，Y轴
	pDC->MoveTo(myleft,size.cy-mybottom);
	pDC->LineTo(size.cx,size.cy-mybottom);
	//Y轴从图形区域最底端到最顶端
	pDC->MoveTo(myleft,size.cy-mybottom);
	pDC->LineTo(myleft,0);
	//确定每个显示刻度之间的宽度
	CString str;
	double factor_x=(rect.Width()-myleft-20)/800;
	//X轴
	for(int i=0;i<(size.cx-myleft)/(5*factor_x);i++)
	{			
		pDC->MoveTo(myleft+5*i,size.cy-mybottom);
		pDC->LineTo(myleft+5*i,size.cy-mybottom+5);
	}
	for (int i=0;i<(size.cx-myleft)/(50*factor_x);i++)
	{
		str.Format(_T("%d"),i*50);	
		pDC->MoveTo(myleft+50*i,size.cy-mybottom);
		pDC->LineTo(myleft+50*i,size.cy-mybottom+15);
		pDC->TextOut(myleft+50*i-10,size.cy-(mybottom-15),str);	
	}

	double maxY=frequent[0];
	for (int i=0;i<160;i++)
	{
		maxY=maxY>frequent[i]?maxY:frequent[i];
	}
	double factor_y=(rect.Height()-mybottom-20)/maxY;
	//y轴
	if (m_radio_energy==0)
	{
		for(int i=0;i<(size.cy-mybottom)/(50*factor_y);i++)
		{
			str.Format(_T("%d"),i*50);
			pDC->MoveTo(myleft-5,size.cy-(mybottom+50*factor_y*i));
			pDC->LineTo(myleft,size.cy-(mybottom+50*factor_y*i));
			pDC->TextOut(myleft-50,size.cy-(mybottom+50*factor_y*i+5),str);
		}
	}
	if (m_radio_energy==1)
	{
		for(int i=0;i<(size.cy-mybottom)/(1000*factor_y);i++)
		{
			str.Format(_T("%d"),i*1000);
			pDC->MoveTo(myleft-5,size.cy-(mybottom+1000*factor_y*i));
			pDC->LineTo(myleft,size.cy-(mybottom+1000*factor_y*i));
			pDC->TextOut(myleft-50,size.cy-(mybottom+1000*factor_y*i+5),str);
		}
	}
	if (m_radio_energy==2)
	{
		for(int i=0;i<(size.cy-mybottom)/(3000*factor_y);i++)
		{
			str.Format(_T("%d"),i*3000);
			pDC->MoveTo(myleft-5,size.cy-(mybottom+3000*factor_y*i));
			pDC->LineTo(myleft,size.cy-(mybottom+3000*factor_y*i));
			pDC->TextOut(myleft-50,size.cy-(mybottom+3000*factor_y*i+5),str);
		}
	}
	
	//绘制X，Y轴的变量名
	pDC->TextOut(size.cx/2,size.cy-20,_T("Energy(kev)"));
	pDC->TextOut(0,3,_T("Distribute"));


	//写图例
	if (m_radio_energy==2)
	{
		pDC->TextOut(size.cx-800,90,_T("Energy Resolution=["));
		str.Format(_T("%.2f"),Energy_Resolution[0]);
		pDC->TextOut(size.cx-630,90,str+_T("]%"));
	}

	if (m_radio_energy==0)
	{
		pDC->TextOut(size.cx-800,60,_T("B["));
		str.Format(_T("%d"),m_board_energy);
		pDC->TextOut(size.cx-780,60,str+_T("]-CH["));
		str.Format(_T("%d"),m_chann_energy);
		pDC->TextOut(size.cx-730,60,str+_T("]"));
		pDC->TextOut(size.cx-800,90,_T("Energy Resolution=["));
		str.Format(_T("%.2f"),Energy_Resolution[0]);
		pDC->TextOut(size.cx-630,90,str+_T("]%"));
	}

	if (m_radio_energy==1)
	{
		pDC->TextOut(size.cx-800,60,_T("B["));
		str.Format(_T("%d"),m_board_energy2);
		pDC->TextOut(size.cx-780,60,str+_T("]"));
		pDC->TextOut(size.cx-800,90,_T("Energy Resolution=["));
		str.Format(_T("%.2f"),Energy_Resolution[0]);
		pDC->TextOut(size.cx-630,90,str+_T("]%"));
	}
	////标注拟合点
	//for (int i=0;i<8;i++)
	//{	
	//	if (i<4)
	//	{	
	//		pDC->BeginPath(); 
	//		pDC->Ellipse(myleft+m_sample[samplenum].Time[i]*5.5-6,rect.Height()-mybottom-m_threshold[i]*factor-6,
	//			myleft+m_sample[samplenum].Time[i]*5.5+6,rect.Height()-mybottom-m_threshold[i]*factor+6); 
	//		pDC->EndPath(); 
	//		pDC->SelectObject(&Brush); 
	//		pDC->FillPath(); 
	//	}
	//	else
	//	{	
	//		pDC->BeginPath(); 
	//		pDC->Ellipse(myleft+m_sample[samplenum].Time[i]*5.5-6,rect.Height()-mybottom-m_threshold[7-i]*factor-6,
	//			myleft+m_sample[samplenum].Time[i]*5.5+6,rect.Height()-mybottom-m_threshold[7-i]*factor+6); 
	//		pDC->EndPath(); 
	//		pDC->SelectObject(&Brush); 
	//		pDC->FillPath(); 
	//	}
	//}


	CBrush Brush;
	Brush.CreateSolidBrush(RGB(255,0,0));
	pDC->SelectObject(Brush);
	//绘制曲线。由于绘图坐标的Y轴是向下延升，所以这里每个点的Y值是用
	//图象高度减去y值大小
	for (int i=0;i<160;i++)
	{
		pDC->Rectangle(myleft+5*i,size.cy-mybottom-frequent[i]*factor_y,myleft+5*i+5,size.cy-mybottom);
	}


	//释放设备描述符
	ReleaseDC(pDC);
}

void CDataShowDlg::energydata_process()
{
	byte temp_double[8],temp_ushort[2];
	m_energy=new double[65536*1014/26];
	x=new BYTE[65536*1014/26];
	memset(x,0,65536*1014/26);
	y=new BYTE[65536*1014/26];
	memset(y,0,65536*1014/26);
	for (int i = 0;i < 65536*1014/26;i++)
	{
		if (i == 65536*1014/26)
		{
			m_energydatapos=20;
		}
		for (int m = 0;m < 8;m++)
		{
			temp_double[m] = *(m_energy_data + m  + i * 26);
		}	
		m_energy[i]= *(double*)&temp_double;
		for (int j = 0;j < 2;j++)
		{
			temp_ushort[j]=*(m_energy_data +j+24+ i*26);			
		}
		USHORT Serial_NUM = *(USHORT*)&temp_ushort;
		x[i]=Serial_NUM /72;
		y[i]=Serial_NUM %72;
		check2[y[i]][x[i]]=1;
	}
	for (int i=0;i<65536*1014/26;i++)
	{
		frequent[(int)(m_energy[i]/5.0+0.5)]++;
	}
	m_energydatapos=40;
	delete[]m_energy_data;
	m_energy_data = NULL;
	if (!ERcalculateInitialize())
	{		
	}	
	m_energydatapos=90;
	mwArray output(1, 1, mxDOUBLE_CLASS);
	mwArray energy(1, 65536*1014/26, mxDOUBLE_CLASS);
	energy.SetData(m_energy,65536*1014/26);	
	ERcalculate(1,output,energy);
	output.GetData(Energy_Resolution,1);
	m_energydatapos=100;
}

DWORD WINAPI CDataShowDlg::TimeThread(LPVOID lpParam)
{
	CDataShowDlg* pDlg = (CDataShowDlg*)lpParam;
	pDlg->timedata_process();
	return 0;
}

void CDataShowDlg::timedata_process()
{
	byte temp_double[8],temp_ushort[2];
	Fir_sample_time=new double[65536*1014/26];
	Serial_NUM=new USHORT[65536*1014/26];
	for (int i = 0;i < 65536*1014/26;i++)
	{
		for (int m = 0;m < 8;m++)
		{
			temp_double[m] = *(m_energy_data + m+16+ i * 26);
		}	
		Fir_sample_time[i]= *(double*)&temp_double;
		for (int j = 0;j < 2;j++)
		{
			temp_ushort[j]=*(m_energy_data +j+24+ i*26);			
		}
		Serial_NUM[i]= *(USHORT*)&temp_ushort;
	}
}

void CDataShowDlg::OnBnClickedRunsamples()
{
	// TODO: 在此添加控件通知处理程序代码
	//RenderScene();
	DrawSamplefigure();
    CButton *Run=(CButton*)GetDlgItem(IDC_RUNSAMPLES);
	Run->EnableWindow(FALSE);
}


void CDataShowDlg::OnBnClickedSavefigure()
{
	// TODO: 在此添加控件通知处理程序代码
	//read the bitmap data and create a bitmap
	FILE* fp;


	BITMAPINFOHEADER header;
	CSize size = getClientbmpsize();
	header.biWidth = size.cx;
	header.biHeight = size.cy;
	header.biSizeImage = 3* size.cx*size.cy;
	header.biSize = 40;
	header.biPlanes = 1;
	header.biBitCount = 3 * 8;
	header.biCompression = 0;
	header.biXPelsPerMeter = 0;
	header.biYPelsPerMeter = 0;
	header.biClrUsed = 0;
	header.biClrImportant = 0;

	BITMAPFILEHEADER fileheader;
	fileheader.bfType = 'MB';
	fileheader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * size.cx*size.cy;
	fileheader.bfReserved1 = 0;
	fileheader.bfReserved2 = 0;
	fileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

	CString strFilter = _T("bmp files(*.bmp)|*.bmp||");
	CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter, NULL);
	CString strPath;

	if (dlg.DoModal() == IDOK)
	{
		strPath = dlg.GetPathName();

		ASSERT(strPath);
		strPath = strPath + _T(".bmp");
		char p[255];
		int i = 0;
		for (i = 0;i < strPath.GetLength();i++)
		{
			p[i] = strPath.GetAt(i);
		}
		p[i] = '\0';
		
		if ((fp = fopen(p,"wb")) == NULL)
		{
			MessageBox(_T("can't open the file!error"), MB_OK);
			return;
		}
		if (fwrite(&fileheader, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER))
		{
			MessageBox(_T("couldn't write the file header!error"), MB_OK);
			fclose(fp);
			return;
		}

		if (fwrite(&header, 1, sizeof(BITMAPINFOHEADER), fp) < sizeof(BITMAPINFOHEADER))
		{
			MessageBox(_T("couldn't write the bitmap header!error"), MB_OK);
			fclose(fp);
			return;
		}

		if (fwrite(pPixelData, 1, 3 * size.cx*size.cy, fp) <  3 * size.cx*size.cy)
		{
			MessageBox(_T("couldn't write the bitmap bits!error"), MB_OK);
			fclose(fp);
			return;
		}
		fclose(fp);
	}

	delete[]pPixelData;
}


void CDataShowDlg::OnBnClickedSamplesetting()
{
	// TODO: 在此添加控件通知处理程序代码
	CSample dlg;
	dlg.m_thresh1.Format(_T("%d"), Cini::ReadInt(_T("Sample"), _T("Threshold1"), _T("DataShow.ini")));
	dlg.m_thresh2.Format(_T("%d"), Cini::ReadInt(_T("Sample"), _T("Threshold2"), _T("DataShow.ini")));
	dlg.m_thresh3.Format(_T("%d"), Cini::ReadInt(_T("Sample"), _T("Threshold3"), _T("DataShow.ini")));
	dlg.m_thresh4.Format(_T("%d"), Cini::ReadInt(_T("Sample"), _T("Threshold4"), _T("DataShow.ini")));
	dlg.m_radio=Cini::ReadInt(_T("Sample"), _T("Radio"), _T("DataShow.ini"));
	dlg.m_channelvalue=Cini::ReadInt(_T("Sample"), _T("channelvalue"), _T("DataShow.ini"));
	dlg.m_boardnum=Cini::ReadInt(_T("Sample"), _T("boardnum"), _T("DataShow.ini"));
	UpdateData(FALSE);
	if (IDOK == dlg.DoModal())
	{
		m_threshold[0] = _ttoi(dlg.m_thresh1);
		m_threshold[1] = _ttoi(dlg.m_thresh2);
		m_threshold[2] = _ttoi(dlg.m_thresh3);
		m_threshold[3] = _ttoi(dlg.m_thresh4);

		m_boardnum = dlg.m_boardnum;
		m_channel = dlg.m_channelvalue;
		m_radio=dlg.m_radio;
		//保存ini各项值	
		CString str;
		str.Format(_T("%d"), m_threshold[0]);
		Cini::WriteString(_T("Sample"), _T("Threshold1"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), m_threshold[1]);
		Cini::WriteString(_T("Sample"), _T("Threshold2"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), m_threshold[2]);
		Cini::WriteString(_T("Sample"), _T("Threshold3"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), m_threshold[3]);
		Cini::WriteString(_T("Sample"), _T("Threshold4"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), m_radio);
		Cini::WriteString(_T("Sample"), _T("Radio"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), dlg.m_boardnum);
		Cini::WriteString(_T("Sample"), _T("boardnum"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), dlg.m_channelvalue);
		Cini::WriteString(_T("Sample"), _T("channelvalue"), str, _T("DataShow.ini"));
	}
}


void CDataShowDlg::OnBnClickedFilepath()
{
	// TODO: 在此添加控件通知处理程序代码
	TCHAR szFilter[] = _T("BINARY(*.samples)|*.samples|BINARY(*.singles)|*.singles|BINARY(*.coins)|*.coins||");
	// 构造打开文件对话框   
	CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, szFilter, this);

	// 显示打开文件对话框   
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“打开”按钮，则将选择的文件路径显示到编辑框里   
		strFilePath = fileDlg.GetPathName();//文件名保存在了FilePathName里
		fileExt=fileDlg.GetFileExt();
		SetDlgItemText(IDC_FILE_OPEN, strFilePath);	
		if (fileExt==_T("samples"))
		{
			try
			{
				CStdioFile file;
				file.Open(strFilePath, CFile::modeRead|CFile::typeBinary);
				CFileStatus fileStatus;
				if (CFile::GetStatus(strFilePath, fileStatus))
				{
					m_filelength = fileStatus.m_size;
					m_sample_data = new BYTE[m_filelength];
				}
				file.Read(m_sample_data, m_filelength);
				file.Close();
			}
			catch (CFileException* e)
			{
				e->ReportError();
				e->Delete();
			}			
			CRITICAL_SECTION g_cs;
			InitializeCriticalSection(&g_cs);
			HANDLE Sample_HAN = CreateThread(NULL, 0, SampleThread, this, 0, NULL);
			CloseHandle(Sample_HAN);
			DeleteCriticalSection(&g_cs);
			CDataProcess dlg;
			dlg.DoModal();	
			CButton *Run=(CButton*)GetDlgItem(IDC_RUNSAMPLES);
			Run->EnableWindow(true);
		}
		if (fileExt==_T("singles")||fileExt==_T("coins"))
		{
			// 创建文件对象
			HANDLE hFile = ::CreateFile(strFilePath, GENERIC_READ,FILE_SHARE_READ, NULL,
				OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
			if (hFile == INVALID_HANDLE_VALUE)
			{
				TRACE("创建文件对象失败,错误代码:%d\r\n", GetLastError());
				return;
			}
			// 创建文件映射对象
			HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
			if (hFileMap == NULL)
			{
				TRACE("创建文件映射对象失败,错误代码:%d\r\n", GetLastError());  
				return;
			}
			// 得到系统分配粒度
			SYSTEM_INFO SysInfo;
			GetSystemInfo(&SysInfo);
			DWORD dwGran = SysInfo.dwAllocationGranularity;
			// 得到文件尺寸
			DWORD dwFileSizeHigh;
			__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
			qwFileSize |= (((__int64)dwFileSizeHigh) << 32);///MSDN
			// 偏移地址
			__int64 qwFileOffset = 0;
			__int64 T_newmap = 900 * dwGran;
			// 块大小
			DWORD dwBlockBytes = 1014 * dwGran;//文件数据分段大小
			if (qwFileSize - qwFileOffset < dwBlockBytes)
				dwBlockBytes = (DWORD)qwFileSize;
			// 映射视图
			char *lpbMapAddress = (char *)MapViewOfFile(hFileMap,FILE_MAP_READ,
				(DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),dwBlockBytes);
			if (lpbMapAddress == NULL)
			{
				TRACE("映射文件映射失败,错误代码:%d ", GetLastError());
				return;
			} 
			// 关闭文件对象
			CloseHandle(hFile); 
			///////////读文件数据
		
			if(qwFileOffset < qwFileSize)
			{
				/********************            读文件             ***************************/  
				//read_eh(&lpbMapAddress)读取已映射到内存的数据，并将文件指针作相应后移(lpbMapAddress++),返回指针偏移量
				m_energy_data=new BYTE[dwBlockBytes];
				memcpy(m_energy_data,lpbMapAddress,dwBlockBytes);
				lpbMapAddress+=dwBlockBytes;
				CRITICAL_SECTION g_cs;
				InitializeCriticalSection(&g_cs);
				if (fileExt==_T("singles"))
				{										
					HANDLE Energy_HAN = CreateThread(NULL, 0, EnergyThread, this, 0, NULL);
					CloseHandle(Energy_HAN);
				}
			
				if (fileExt==_T("coins"))
				{
					HANDLE Mtime_HAN = CreateThread(NULL, 0, TimeThread, this, 0, NULL);
					CloseHandle(Mtime_HAN);
				}
				//Sleep(500);				
				DeleteCriticalSection(&g_cs);
				qwFileOffset = qwFileOffset +dwBlockBytes; //修改偏移量
				if (qwFileOffset > T_newmap)
				{//当数据读到90%时,为防数据溢出,需要映射在其后的数据  T_newmap
					UnmapViewOfFile(lpbMapAddress);//释放当前映射
					if ((DWORD)(qwFileSize - T_newmap) < dwBlockBytes)
						dwBlockBytes = (DWORD)(qwFileSize - T_newmap);
					lpbMapAddress = (char *)MapViewOfFile(hFileMap,FILE_MAP_READ,
						(DWORD)(T_newmap >> 32), (DWORD)(T_newmap & 0xFFFFFFFF),dwBlockBytes);
					// 修正参数
					lpbMapAddress = lpbMapAddress + qwFileOffset - T_newmap;
					T_newmap =T_newmap  + 900 * dwGran;
					if (lpbMapAddress == NULL)
					{
						TRACE("映射文件映射失败,错误代码:%d ", GetLastError());
						return;
					}
				}
			}
			//释放最后数据块映射
			UnmapViewOfFile(lpbMapAddress);
			// 关闭文件映射对象句柄
			CloseHandle(hFileMap);  

			//CDataProcess dlg;
			//dlg.DoModal();

		
			CButton *Run=(CButton*)GetDlgItem(IDC_ENERGYRUN);
			Run->EnableWindow(true);	
		}

	}
	else
	{
		return;
	}
}


void CDataShowDlg::OnBnClickedSamplenext()
{
	// TODO: 在此添加控件通知处理程序代码
	mwArray x(1, 8, mxDOUBLE_CLASS);
	mwArray th(1, 4, mxDOUBLE_CLASS);
	mwArray plotdata(1, 15002, mxDOUBLE_CLASS);
	if (m_radio==0)
	{	
		for (int i=samplenum+1;i<m_filelength/67;i++)
	    {
			if (m_sample[i].boardnum==m_boardnum-1&&m_sample[i].channel==m_channel-1)
			{
				x.SetData(m_sample[i].Time, 8);
				th.SetData(m_threshold, 4);		
				SingleDouble(1, plotdata, th, x);
				plotdata.GetData(sampleplotdata,15002);
				samplenum=i;
				DrawSamplefigure();
				break;
			}
			if (i==m_filelength/67-1)
			{
				MessageBox(_T("数据中无选定通道"));
				return;
			}
	    }			
	}
	else{
		samplenum=rand()%(m_filelength/67);
	    x.SetData(m_sample[samplenum].Time, 8);
	    th.SetData(m_threshold, 4);		
	    SingleDouble(1, plotdata, th, x);
	    plotdata.GetData(sampleplotdata,15002);
	    DrawSamplefigure();
		samplenum=0;
	}
}

void CDataShowDlg::OnBnClickedEnergysetting()
{
	// TODO: 在此添加控件通知处理程序代码
	CEnergy dlg;
	dlg.m_radio=Cini::ReadInt(_T("Energy"), _T("Radio"), _T("DataShow.ini"));
	dlg.m_channelvalue=Cini::ReadInt(_T("Energy"), _T("channelvalue"), _T("DataShow.ini"));
	dlg.m_boardnum=Cini::ReadInt(_T("Energy"), _T("boardnum"), _T("DataShow.ini"));
	dlg.m_boardnum2=Cini::ReadInt(_T("Energy"), _T("boardnum2"), _T("DataShow.ini"));
	if (IDOK == dlg.DoModal())
	{
		m_board_energy = dlg.m_boardnum;
		m_board_energy2 = dlg.m_boardnum2;
		m_chann_energy = dlg.m_channelvalue;
		m_radio_energy=dlg.m_radio;

		//保存ini各项值	
		CString str;
		str.Format(_T("%d"), dlg.m_radio);
		Cini::WriteString(_T("Energy"), _T("Radio"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), dlg.m_channelvalue);
		Cini::WriteString(_T("Energy"), _T("channelvalue"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), dlg.m_boardnum);
		Cini::WriteString(_T("Energy"), _T("boardnum"), str, _T("DataShow.ini"));
		str.Format(_T("%d"), dlg.m_boardnum2);
		Cini::WriteString(_T("Energy"), _T("boardnum2"), str, _T("DataShow.ini"));
	}
}


void CDataShowDlg::OnBnClickedEnergyrun()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_radio_energy==2)
	{
		mwArray output(1, 1, mxDOUBLE_CLASS);
		mwArray energy(1, 65536*1014/26, mxDOUBLE_CLASS);
		energy.SetData(m_energy,65536*1014/26);	
		ERcalculate(1,output,energy);
		output.GetData(Energy_Resolution,1);
		memset(frequent,0,sizeof(long)*160);
		for (int i=0;i<65536*1014/26;i++)
		{
			frequent[(int)(m_energy[i]/5.0+0.5)]++;
		}
		DrawEnergyfigure();
		CButton *next=(CButton*)GetDlgItem(IDC_ENERGYNEXT);
		next->EnableWindow(FALSE);	
	}
	mwArray output(1, 1, mxDOUBLE_CLASS);
	
	
	if (m_radio_energy==0)
	{	
		
		CArray <double,double&> energy_appoint;
		energy_appoint.SetSize(0);
		for (int i=0;i<65536*1014/26;i++)
		{
			if (x[i]==m_board_energy-1&&y[i]==m_chann_energy-1)
			{
				energy_appoint.Add(m_energy[i]);
			}
		}	
		if (!energy_appoint.IsEmpty())
		{
			memset(frequent,0,sizeof(long)*160);
			for (int j=0;j<energy_appoint.GetSize();j++)
			{
				frequent[(int)(energy_appoint.GetAt(j)/5.0+0.5)]++;
			}
			mwArray energy(1, energy_appoint.GetSize(), mxDOUBLE_CLASS);
			energy.SetData(energy_appoint.GetData(),energy_appoint.GetSize());
			ERcalculate(1,output,energy);
			output.GetData(Energy_Resolution,1);
			DrawEnergyfigure();
		}
		else
		{
			MessageBox(_T("数据中无匹配"));
			return;
		}	
		CButton *next=(CButton*)GetDlgItem(IDC_ENERGYNEXT);
		next->EnableWindow(true);	
	}
	if (m_radio_energy==1)
	{
	
		CArray <double,double&> energy_appoint2;
		energy_appoint2.SetSize(0);
		for (int i=0;i<65536*1014/26;i++)
		{
			if (x[i]==m_board_energy2-1)
			{
				energy_appoint2.Add(m_energy[i]);
			}
		}	
		if (!energy_appoint2.IsEmpty())
		{
			memset(frequent,0,sizeof(long)*160);
			for (int j=0;j<energy_appoint2.GetSize();j++)
			{
				frequent[(int)(energy_appoint2.GetAt(j)/5.0+0.5)]++;
			}
			mwArray energy(1, energy_appoint2.GetSize(), mxDOUBLE_CLASS);
			energy.SetData(energy_appoint2.GetData(),energy_appoint2.GetSize());
			ERcalculate(1,output,energy);
			output.GetData(Energy_Resolution,1);
			DrawEnergyfigure();
		}
		else
		{
			MessageBox(_T("数据中无匹配"));
			return;
		}	
		CButton *next=(CButton*)GetDlgItem(IDC_ENERGYNEXT);
		next->EnableWindow(true);	
	}
}


void CDataShowDlg::OnBnClickedEnergynext()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_radio_energy==0)
	{
		if (m_chann_energy!=72)
		{
			m_chann_energy++;
		}
		else{
			if (m_board_energy!=6)
			{
				m_board_energy++;
			}
			else{
				m_board_energy=1;
				m_chann_energy=1;
			}
		}
		OnBnClickedEnergyrun();
	}
	if (m_radio_energy==1)
	{
		if (m_board_energy2!=6)
		{
			m_board_energy2++;
		}
		else{
			m_board_energy2=1;
		}
		OnBnClickedEnergyrun();
	}
}


void CDataShowDlg::OnBnClickedTimesetting()
{
	// TODO: 在此添加控件通知处理程序代码
	CMtime dlg;
	if (IDOK == dlg.DoModal())
	{

	}

}
